package book

import (
	"time"

	"BookStack/pkg/errors"
	"BookStack/pkg/utils"
)

// 书籍状态常量
const (
	BookStatusDraft     int = 0 // 草稿
	BookStatusPublished int = 1 // 已发布
	BookStatusArchived  int = 2 // 已归档
)

// 书籍推荐状态常量
const (
	BookRecommendNone   int = 0 // 不推荐
	BookRecommendNormal int = 1 // 普通推荐
	BookRecommendHot    int = 2 // 热门推荐
)

// Book 书籍实体
type Book struct {
	ID           uint       `json:"id" gorm:"primaryKey"`
	Title        string     `json:"title" gorm:"size:200;not null;index"`
	Slug         string     `json:"slug" gorm:"size:255;uniqueIndex;not null"`
	Author       string     `json:"author" gorm:"size:100;not null"`
	Description  string     `json:"description" gorm:"type:text"`
	Cover        string     `json:"cover" gorm:"size:255"`
	ISBN         string     `json:"isbn" gorm:"size:20"`
	CategoryID   uint       `json:"category_id" gorm:"index"`
	Status       int        `json:"status" gorm:"default:0"`
	Recommended  int        `json:"recommended" gorm:"default:0"`
	PublishedAt  *time.Time `json:"published_at"`
	ViewCount    int        `json:"view_count" gorm:"default:0"`
	StarCount    int        `json:"star_count" gorm:"default:0"`
	LikeCount    int        `json:"like_count" gorm:"default:0"`
	ChapterCount int        `json:"chapter_count" gorm:"default:0"`
	CreatedBy    uint       `json:"created_by" gorm:"index"`
	UpdatedBy    uint       `json:"updated_by"`
	DeletedBy    uint       `json:"deleted_by"`
	CreatedAt    time.Time  `json:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at"`
	DeletedAt    *time.Time `json:"deleted_at" gorm:"index"`
}

// TableName 返回数据库表名
func (Book) TableName() string {
	return "books"
}

// NewBook 创建新书籍实体
func NewBook(title, slug, author, description, cover, isbn string, categoryID, createdBy uint) (*Book, error) {
	if title == "" {
		return nil, errors.New(errors.ErrCodeBookTitleRequired, "")
	}
	if author == "" {
		return nil, errors.New(errors.ErrCodeBookAuthorRequired, "")
	}
	if slug == "" {
		return nil, errors.New(errors.ErrCodeBookSlugRequired, "")
	}

	now := utils.TimeToJSONTime(time.Now()).Time()
	book := &Book{
		Title:       title,
		Slug:        slug,
		Author:      author,
		Description: description,
		Cover:       cover,
		ISBN:        isbn,
		CategoryID:  categoryID,
		Status:      BookStatusDraft,
		Recommended: BookRecommendNone,
		CreatedBy:   createdBy,
		UpdatedBy:   createdBy,
		CreatedAt:   now,
		UpdatedAt:   now,
	}

	return book, nil
}

// Update 更新书籍基本信息
func (b *Book) Update(title, author, description, cover, isbn string, categoryID, updatedBy uint) error {
	if title == "" {
		return errors.New(errors.ErrCodeBookTitleRequired, "")
	}
	if author == "" {
		return errors.New(errors.ErrCodeBookAuthorRequired, "")
	}

	b.Title = title
	b.Author = author
	b.Description = description
	b.Cover = cover
	b.ISBN = isbn
	b.CategoryID = categoryID
	b.UpdatedBy = updatedBy
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()

	return nil
}

// Publish 发布书籍
func (b *Book) Publish(publishedBy uint) error {
	if b.Status == BookStatusPublished {
		return nil
	}

	now := utils.TimeToJSONTime(time.Now()).Time()
	b.Status = BookStatusPublished
	b.PublishedAt = &now
	b.UpdatedBy = publishedBy
	b.UpdatedAt = now

	return nil
}

// SetStatus 设置书籍状态
func (b *Book) SetStatus(status int, updatedBy uint) error {
	if status < BookStatusDraft || status > BookStatusArchived {
		return errors.New(errors.ErrCodeBookStatusInvalid, "")
	}

	b.Status = status
	b.UpdatedBy = updatedBy
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()

	// 如果是首次发布，设置发布时间
	if status == BookStatusPublished && b.PublishedAt == nil {
		now := utils.TimeToJSONTime(time.Now()).Time()
		b.PublishedAt = &now
	}

	return nil
}

// SetRecommended 设置书籍推荐状态
func (b *Book) SetRecommended(recommended int, updatedBy uint) error {
	if recommended < BookRecommendNone || recommended > BookRecommendHot {
		return errors.New(errors.ErrCodeBookRecommendStatusInvalid, "")
	}

	b.Recommended = recommended
	b.UpdatedBy = updatedBy
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()

	return nil
}

// SoftDelete 软删除（移入回收站）
func (b *Book) SoftDelete(deletedBy uint) {
	now := utils.TimeToJSONTime(time.Now()).Time()
	b.DeletedAt = &now
	b.DeletedBy = deletedBy
	b.UpdatedAt = now
}

// Restore 从回收站恢复
func (b *Book) Restore() {
	b.DeletedAt = nil
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// IncrementViewCount 增加浏览次数
func (b *Book) IncrementViewCount() {
	b.ViewCount++
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// IncrementStarCount 增加收藏次数
func (b *Book) IncrementStarCount() {
	b.StarCount++
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// DecrementStarCount 减少收藏次数
func (b *Book) DecrementStarCount() {
	if b.StarCount > 0 {
		b.StarCount--
		b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
	}
}

// IncrementLikeCount 增加点赞次数
func (b *Book) IncrementLikeCount() {
	b.LikeCount++
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// DecrementLikeCount 减少点赞次数
func (b *Book) DecrementLikeCount() {
	if b.LikeCount > 0 {
		b.LikeCount--
		b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
	}
}

// IncrementChapterCount 增加章节计数
func (b *Book) IncrementChapterCount() {
	b.ChapterCount++
	b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// DecrementChapterCount 减少章节计数
func (b *Book) DecrementChapterCount() {
	if b.ChapterCount > 0 {
		b.ChapterCount--
		b.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
	}
}

// Chapter 章节实体
type Chapter struct {
	ID        uint       `json:"id" gorm:"primaryKey"`
	BookID    uint       `json:"book_id" gorm:"index;not null"`
	ParentID  uint       `json:"parent_id" gorm:"index;default:0"` // 父章节ID，0表示顶级章节
	Title     string     `json:"title" gorm:"size:200;not null"`
	Slug      string     `json:"slug" gorm:"size:255"`
	Content   string     `json:"content" gorm:"type:longtext"`
	Order     int        `json:"order" gorm:"index;not null"`
	ViewCount int        `json:"view_count" gorm:"default:0"`
	WordCount int        `json:"word_count" gorm:"default:0"`
	CreatedBy uint       `json:"created_by"`
	UpdatedBy uint       `json:"updated_by"`
	DeletedBy uint       `json:"deleted_by"`
	CreatedAt time.Time  `json:"created_at"`
	UpdatedAt time.Time  `json:"updated_at"`
	DeletedAt *time.Time `json:"deleted_at" gorm:"index"`
}

// TableName 返回数据库表名
func (Chapter) TableName() string {
	return "book_chapters"
}

// NewChapter 创建新章节实体
func NewChapter(bookID uint, title, slug, content string, order int, createdBy uint) (*Chapter, error) {
	if title == "" {
		return nil, errors.New(errors.ErrCodeChapterTitleRequired, "")
	}
	if content == "" {
		return nil, errors.New(errors.ErrCodeChapterContentRequired, "")
	}
	if bookID == 0 {
		return nil, errors.New(errors.ErrCodeChapterBookIDRequired, "")
	}

	now := utils.TimeToJSONTime(time.Now()).Time()
	wordCount := countWords(content)

	chapter := &Chapter{
		BookID:    bookID,
		Title:     title,
		Slug:      slug,
		Content:   content,
		Order:     order,
		WordCount: wordCount,
		CreatedBy: createdBy,
		UpdatedBy: createdBy,
		CreatedAt: now,
		UpdatedAt: now,
	}

	return chapter, nil
}

// Update 更新章节内容
func (c *Chapter) Update(title, content string, updatedBy uint) error {
	if title == "" {
		return errors.New(errors.ErrCodeChapterTitleRequired, "")
	}
	if content == "" {
		return errors.New(errors.ErrCodeChapterContentRequired, "")
	}

	c.Title = title
	c.Content = content
	c.WordCount = countWords(content)
	c.UpdatedBy = updatedBy
	c.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()

	return nil
}

// UpdateOrder 更新章节顺序
func (c *Chapter) UpdateOrder(order int, updatedBy uint) error {
	if order < 0 {
		return errors.New(errors.ErrCodeChapterOrderInvalid, "")
	}

	c.Order = order
	c.UpdatedBy = updatedBy
	c.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()

	return nil
}

// SoftDelete 软删除章节
func (c *Chapter) SoftDelete(deletedBy uint) {
	now := utils.TimeToJSONTime(time.Now()).Time()
	c.DeletedAt = &now
	c.DeletedBy = deletedBy
	c.UpdatedAt = now
}

// Restore 恢复已删除章节
func (c *Chapter) Restore() {
	c.DeletedAt = nil
	c.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// IncrementViewCount 增加章节浏览次数
func (c *Chapter) IncrementViewCount() {
	c.ViewCount++
	c.UpdatedAt = utils.TimeToJSONTime(time.Now()).Time()
}

// RecycleItem 回收站项目实体
type RecycleItem struct {
	ID          uint       `json:"id" gorm:"primaryKey"`
	ItemID      uint       `json:"item_id" gorm:"index;not null"` // 被删除项目的ID
	ItemType    string     `json:"item_type" gorm:"not null"`     // 项目类型，如book, chapter
	Title       string     `json:"title" gorm:"size:200;not null"`
	Description string     `json:"description" gorm:"type:text"`
	Data        string     `json:"data" gorm:"type:longtext"` // 项目的JSON备份数据
	DeletedBy   uint       `json:"deleted_by"`
	CreatedAt   time.Time  `json:"created_at"` // 创建时间就是删除时间
	RestoredAt  *time.Time `json:"restored_at"`
}

// TableName 返回数据库表名
func (RecycleItem) TableName() string {
	return "book_recycle_bin"
}

// NewRecycleItem 创建新的回收站项目
func NewRecycleItem(itemID uint, itemType, title, description, data string, deletedBy uint) (*RecycleItem, error) {
	if itemID == 0 {
		return nil, errors.New(errors.ErrCodeRecycleItemIDRequired, "")
	}
	if itemType == "" {
		return nil, errors.New(errors.ErrCodeRecycleItemInvalid, "")
	}

	recycleItem := &RecycleItem{
		ItemID:      itemID,
		ItemType:    itemType,
		Title:       title,
		Description: description,
		Data:        data,
		DeletedBy:   deletedBy,
		CreatedAt:   utils.TimeToJSONTime(time.Now()).Time(),
	}

	return recycleItem, nil
}

// MarkRestored 标记项目为已恢复
func (r *RecycleItem) MarkRestored() {
	now := utils.TimeToJSONTime(time.Now()).Time()
	r.RestoredAt = &now
}

// 辅助函数：简单的字数统计（中英文均按一个字计算）
func countWords(content string) int {
	return len([]rune(content))
}
